﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameField
{
    class NodeGameLogic
    {
        private Random rndgen;
        private List<GameNode> nodesList = new List<GameNode>();
        private List<GameNode> winnerList = new List<GameNode>();
        private GameField gameField;
        private Drawer drawer;
        private int nodeCount;
        private GameNode exitNode;



        public NodeGameLogic(GameField gameField, Drawer drawer, int nodeCount)
        {
            this.rndgen = new Random();
            this.nodesList = new List<GameNode>();
            this.gameField = gameField;
            this.drawer = drawer;
            this.nodeCount = nodeCount;
            this.exitNode = new GameNode(0, 0, '@');

        }
        public void StartGame()
        {
            drawer.DrawGameField(gameField, '*');
            GenerateRrandomNodes();
            GenerateExitNode();
            do
            {
                Console.Clear();
                winnerList.Clear();
                drawer.DrawGameField(gameField, '*');
                GenerateNodeCoordinates();
                GenerateExitNode();

                for (int i = 0; i < nodesList.Count; i++)
                {
                    drawer.DrawGameNode(nodesList[i]);
                }
                Console.ForegroundColor = ConsoleColor.Red;
                drawer.DrawGameNode(exitNode);
                Console.ForegroundColor = ConsoleColor.White;


                do
                {
                    for (int i = 0; i < nodesList.Count; i++)
                    {

                        int choiceNodeMove = rndgen.Next(1, 5);
                        drawer.ClearGameNode(nodesList[i]);

                        switch (choiceNodeMove)
                        {
                            case 1:
                                {
                                    if (IsMovable(nodesList[i].X, nodesList[i].Y + 1) && IsOnField(nodesList[i].X, nodesList[i].Y + 1))
                                    {

                                        nodesList[i].MoveDown();

                                    }
                                    break;
                                }

                            case 2:

                                if (IsMovable(nodesList[i].X, nodesList[i].Y - 1)&& IsOnField(nodesList[i].X, nodesList[i].Y - 1))
                                {
                                    nodesList[i].MoveUp();
                                }
                                break;

                            case 3:
                                if (IsMovable(nodesList[i].X - 1, nodesList[i].Y) && IsOnField(nodesList[i].X - 1, nodesList[i].Y))
                                {
                                    nodesList[i].MoveLeft();
                                }
                                break;

                            case 4:
                                if (IsMovable(nodesList[i].X + 1, nodesList[i].Y) && IsOnField(nodesList[i].X + 1, nodesList[i].Y))
                                {
                                    nodesList[i].MoveRight();
                                }
                                break;
                        }
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        drawer.DrawGameNode(nodesList[i]);
                        Console.ForegroundColor = ConsoleColor.White;

                        if (IsOnExit())
                        {
                            drawer.ClearGameNode(nodesList[i]);
                            Console.ForegroundColor = ConsoleColor.Red;
                            drawer.DrawGameNode(exitNode);
                            Console.ForegroundColor = ConsoleColor.White;
                            winnerList.Add(nodesList[i]);
                            nodesList.Remove(nodesList[i]);

                        }
                    }
                }

                while (nodesList.Count > 1);

                Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 5, gameField.GameFieldY);
                Console.WriteLine("Winners");
                for (int i = 0; i < winnerList.Count; i++)
                {
                    Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 5, gameField.GameFieldY + 2 + i);
                    Console.WriteLine(winnerList[i].NodeSymbol);
                }

                Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 15, gameField.GameFieldY);
                Console.WriteLine("Losers");
                for (int i = 0; i < nodesList.Count; i++)
                {
                    Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 15, gameField.GameFieldY + 2 + i);
                    Console.WriteLine(nodesList[i].NodeSymbol);
                }
                nodesList.Clear();

                for (int i = 0; i < winnerList.Count; i++)
                {

                    nodesList.Add(winnerList[i]);
                }
                Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 15, gameField.GameFieldY + 12);
                Console.WriteLine("Press any key for continue");
                Console.ReadKey();

            }

            while (winnerList.Count > 1);

        }



        public bool IsMovable(int x, int y)
        {
            foreach (var n in nodesList)
                if (n.X == x && n.Y == y)
                    return false;
            return true;
        }

        public void GenerateRrandomNodes()
        {
            for (int i = 0; i < nodeCount; i++)
            {

                int newX = rndgen.Next(gameField.GameFieldX, (gameField.Width + gameField.GameFieldX - 1));
                int newY = rndgen.Next(gameField.GameFieldY + 1, (gameField.Height + gameField.GameFieldY - 1));
                if (IsMovable(newX, newY))
                {

                    nodesList.Add(new GameNode(newX, newY, (Char)(i + 20)));
                }
                else
                {
                    i--;
                }

            }

        }
        public void GenerateNodeCoordinates()
        {
            for (int i = 0; i < nodesList.Count; i++)
            {
                int newX = rndgen.Next(gameField.GameFieldX, (gameField.Width + gameField.GameFieldX - 1));
                int newY = rndgen.Next(gameField.GameFieldY + 1, (gameField.Height + gameField.GameFieldY - 1));
                if (IsMovable(newX, newY))
                {
                    nodesList[i].X = newX;
                    nodesList[i].Y = newY;
                }
                else
                {
                    i--;
                }
            }

        }
        public void GenerateExitNode()
        {

            for (int i = 0; i < 1; i++)
            {

                int newX = rndgen.Next(gameField.GameFieldX, (gameField.Width + gameField.GameFieldX - 1));
                int newY = rndgen.Next(gameField.GameFieldY + 1, (gameField.Height + gameField.GameFieldY - 1));
                if (IsMovable(newX, newY))
                {


                    exitNode.X = newX;
                    exitNode.Y = newY;
                    exitNode.NodeSymbol = '@';

                }
                else
                {
                    i--;
                }

            }


        }

        public bool IsOnField(int x, int y)
        {
            if (x < gameField.GameFieldX || x > gameField.GameFieldX + gameField.Width - 1 || y < gameField.GameFieldY || y > gameField.GameFieldY + gameField.Height - 1)
                return false;
            return true;
        }

        public bool IsOnExit()
        {

            for (int i = 0; i < nodesList.Count; i++)

            {
                if (nodesList[i].X == exitNode.X && nodesList[i].Y == exitNode.Y)
                {

                    return true;
                }

            }
            return false;
        }
    }
}
